#!/usr/bin/env python3
"""
课堂互动信号接收系统测试脚本
"""

import os
import sys
import json
import time
import logging
import threading
import queue
from pathlib import Path
import numpy as np

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("Test-Script")

def test_dependencies():
    """测试依赖项是否正确安装"""
    logger.info("测试依赖项...")
    
    try:
        import streamlit
        logger.info(f"Streamlit 版本: {streamlit.__version__}")
        
        import bleak
        logger.info(f"Bleak 版本: {bleak.__version__}")
        
        import numpy
        logger.info(f"NumPy 版本: {numpy.__version__}")
        
        import pandas
        logger.info(f"Pandas 版本: {pandas.__version__}")
        
        import matplotlib
        logger.info(f"Matplotlib 版本: {matplotlib.__version__}")
        
        return True
    except ImportError as e:
        logger.error(f"依赖项测试失败: {str(e)}")
        return False

def test_file_structure():
    """测试文件结构是否完整"""
    logger.info("测试文件结构...")
    
    required_files = [
        'app.py',
        'bluetooth_listener.py',
        'face_recognizer.py',
        'requirements.txt',
        'data'
    ]
    
    missing_files = []
    for file in required_files:
        if not os.path.exists(file):
            missing_files.append(file)
    
    if missing_files:
        logger.error(f"缺少以下文件或目录: {', '.join(missing_files)}")
        return False
    
    logger.info("文件结构测试通过")
    return True

def test_face_recognizer():
    """测试人脸识别模块"""
    logger.info("测试人脸识别模块...")
    
    try:
        from face_recognizer import FaceRecognizer
        
        # 创建人脸识别器实例
        recognizer = FaceRecognizer(similarity_threshold=0.7)
        
        # 测试数据
        test_face_data = {
            "20226701": {
                "name": "张三",
                "features": [0.12, -0.45, 0.78, 0.32, -0.65]
            },
            "20226702": {
                "name": "李四",
                "features": [0.23, -0.36, 0.65, 0.41, -0.52]
            }
        }
        
        # 加载测试数据
        recognizer.load_face_data(test_face_data)
        
        # 测试用例1：应当匹配到第一个学生
        test_data_1 = {
            "features": [0.13, -0.43, 0.77, 0.33, -0.64]  # 接近第一个学生的特征
        }
        result_1 = recognizer.recognize_face(test_data_1)
        logger.info(f"测试用例1结果: {result_1}")
        
        # 测试用例2：应当匹配到第二个学生
        test_data_2 = {
            "features": [0.24, -0.35, 0.66, 0.42, -0.51]  # 接近第二个学生的特征
        }
        result_2 = recognizer.recognize_face(test_data_2)
        logger.info(f"测试用例2结果: {result_2}")
        
        # 测试用例3：不应当匹配到任何学生
        test_data_3 = {
            "features": [0.8, 0.8, 0.8, 0.8, 0.8]  # 与所有学生都不接近
        }
        result_3 = recognizer.recognize_face(test_data_3)
        logger.info(f"测试用例3结果: {result_3}")
        
        # 测试通过的条件
        test_passed = (
            result_1 == "20226701" and
            result_2 == "20226702" and
            result_3 == "unknown"
        )
        
        if test_passed:
            logger.info("人脸识别模块测试通过")
        else:
            logger.error("人脸识别模块测试失败")
        
        return test_passed
    
    except Exception as e:
        logger.error(f"人脸识别模块测试失败: {str(e)}")
        return False

def test_bluetooth_listener():
    """测试蓝牙监听模块"""
    logger.info("测试蓝牙监听模块...")
    
    try:
        import asyncio
        from bluetooth_listener import simulate_bluetooth_data
        
        # 创建测试队列
        test_queue = queue.Queue()
        
        # 创建测试协程
        async def test_coroutine():
            # 等待接收3条模拟数据
            await simulate_bluetooth_data(test_queue)
            return True
        
        # 创建事件循环
        loop = asyncio.new_event_loop()
        
        # 在单独的线程中运行协程，防止阻塞
        def run_async_test():
            asyncio.set_event_loop(loop)
            try:
                loop.run_until_complete(asyncio.wait_for(test_coroutine(), timeout=5))
            except asyncio.TimeoutError:
                logger.info("蓝牙测试超时（这是预期行为）")
            finally:
                loop.close()
        
        # 启动测试线程
        thread = threading.Thread(target=run_async_test)
        thread.daemon = True
        thread.start()
        
        # 等待数据接收
        timeout = time.time() + 10  # 10秒超时
        received_data = False
        
        while time.time() < timeout:
            if not test_queue.empty():
                data = test_queue.get()
                logger.info(f"接收到蓝牙数据: {data[:50]}...")
                received_data = True
                break
            time.sleep(0.1)
        
        if received_data:
            logger.info("蓝牙监听模块测试通过")
            return True
        else:
            logger.error("蓝牙监听模块测试失败: 未接收到数据")
            return False
    
    except Exception as e:
        logger.error(f"蓝牙监听模块测试失败: {str(e)}")
        return False

def run_tests():
    """运行所有测试"""
    tests = [
        ("依赖项测试", test_dependencies),
        ("文件结构测试", test_file_structure),
        ("人脸识别模块测试", test_face_recognizer),
        ("蓝牙监听模块测试", test_bluetooth_listener)
    ]
    
    results = []
    
    for test_name, test_func in tests:
        logger.info(f"\n{'=' * 50}\n开始 {test_name}\n{'=' * 50}")
        try:
            result = test_func()
            results.append((test_name, result))
        except Exception as e:
            logger.error(f"{test_name} 出现异常: {str(e)}")
            results.append((test_name, False))
    
    # 打印总结
    logger.info(f"\n{'=' * 50}\n测试结果总结\n{'=' * 50}")
    
    all_passed = True
    for test_name, result in results:
        status = "通过" if result else "失败"
        logger.info(f"{test_name}: {status}")
        if not result:
            all_passed = False
    
    if all_passed:
        logger.info("\n所有测试都通过了！系统可以正常运行。")
        return 0
    else:
        logger.error("\n部分测试失败，请检查上面的错误信息。")
        return 1

if __name__ == "__main__":
    print("\n" + "=" * 50)
    print("    课堂互动信号接收系统 - 测试脚本")
    print("=" * 50 + "\n")
    
    sys.exit(run_tests()) 